/*        
	Copyright (C) 2010- Peer internet solutions

	Copyright (C) 2013 Pontificia Universidad Catolica del Peru
	contact: http://avatar.inf.pucp.edu.pe/realidad-aumentada/
	address contact: Av. Universitaria 1801, San Miguel, Lima-Peru.

	This file is part of UbicAR PUCP.
	
	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with This program.  If not, see <http://www.gnu.org/licenses/>.
*/
/*
	Modified by: Pedro Carrión Castagnola
	Pontificia Universidad Catolica del Peru
	Direccion de Informatica Academica

	Modified by: Alvaro Roger Agüero Sánchez, Rodolfo Javier Galvez Meza
	Pontificia Universidad Catolica del Peru
	Departamento de Ingeniería
*/

package org.grupoavatar.guiaubicua;

import static android.hardware.SensorManager.SENSOR_DELAY_GAME;

import java.util.Iterator;
import java.util.List;

import org.grupoavatar.guiaubicua.gestores.GestorConfiguracion;
import org.grupoavatar.guiaubicua.mix.Compatibility;
import org.grupoavatar.guiaubicua.mix.DataView;
import org.grupoavatar.guiaubicua.mix.MixContext;
import org.grupoavatar.guiaubicua.mix.MixState;
import org.grupoavatar.guiaubicua.mix.gui.PaintScreen;
import org.grupoavatar.guiaubicua.mix.render.Matrix;

import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.hardware.Camera;
import android.hardware.GeomagneticField;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.provider.Settings;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.SeekBar;
import android.widget.Toast;

public class VAR extends SherlockActivity implements SensorEventListener,LocationListener{

	static final int DESCARGA_POI = 0;
	public static Dialog d;
	private CameraSurface camScreen;
	private AugmentedView augScreen;

	private MixContext mixContext;
	//public static PaintScreen dWindow;

	private float RTmp[] = new float[9];
	private float Rot[] = new float[9];
	private float I[] = new float[9];
	private float grav[] = new float[3];
	private float mag[] = new float[3];

	private SensorManager sensorMgr;
	private List<Sensor> sensors;
	private Sensor sensorGrav, sensorMag;
	private LocationManager locationMgr;

	private int rHistIdx = 0;
	private Matrix tempR = new Matrix();
	private Matrix finalR = new Matrix();
	private Matrix smoothR = new Matrix();
	private Matrix histR[] = new Matrix[60];
	private Matrix m1 = new Matrix();
	private Matrix m2 = new Matrix();
	private Matrix m3 = new Matrix();
	private Matrix m4 = new Matrix();

	private SeekBar myZoomBar;
	private WakeLock mWakeLock;

	private boolean fError;

	private String zoomLevel;
	private int zoomProgress;

	private ProgressDialog pd;
	
	//AGREGADO para POI LOCKED DIALOG
	private static Context CONTEXT;	
		
	private static VAR vAR;
	
	//AGREGADO para POI LOCKED DIALOG
	public static PaintScreen getPaintScreen() {
		//COMENTADO PARA PROBAR COMPORTAMIENTO ESTATICO
		//return dWindow;
		return GestorConfiguracion.dWindow;
	}
	public static Context getContext() {
		return CONTEXT;
	}
	
	public boolean isZoombarVisible() {
		return myZoomBar != null && myZoomBar.getVisibility() == View.VISIBLE;
	}

	public String getZoomLevel() {
		return zoomLevel;
	}
	
	public int getZoomProgress() {
		return zoomProgress;
	}
	
	public void doError(Exception ex1) {
		if (!fError) {
			fError = true;

			setErrorDialog();

			ex1.printStackTrace();
			try {
			} catch (Exception ex2) {
				ex2.printStackTrace();
			}
		}

		try {
			augScreen.invalidate();
		} catch (Exception ignore) {
		}
	}

	public void killOnError() throws Exception {
		if (fError)
			throw new Exception();
	}

	public void repaint() {
		VInicial.dataView = new DataView(mixContext);
		/* COMENTADO PARA PROBAR COMPORTAMIENTO ESTATICO
		dWindow = new PaintScreen();
		*/
		GestorConfiguracion.dWindow = new PaintScreen();
		setZoomLevel();
	}

	public void setErrorDialog(){
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setMessage(getString(R.string.connection_error_dialog));
		builder.setCancelable(false);
		
		/*Retry*/
		builder.setPositiveButton(R.string.connection_error_dialog_button1, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				fError=false;
	        	finish();
				Intent i = new Intent(VInicial.getContext(), VDownloading.class);
				i.putExtra("sigV", "ar");
				startActivity(i);
			}
		});
		/*Open settings*/
		builder.setNeutralButton(R.string.connection_error_dialog_button2, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				Intent intent1 = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
				startActivityForResult(intent1, 42);
			}
		});
		/*Close application*/
		builder.setNegativeButton(R.string.connection_error_dialog_button3, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				finish();
			}
		});
		AlertDialog alert = builder.create();
		alert.show();
	}

	public void setProgressDialog(){
		pd = new ProgressDialog(this);
		pd.setMessage("Obteniendo ubicación");
		
		pd.setButton("Cancelar", new DialogInterface.OnClickListener() 
	    {
	        public void onClick(DialogInterface dialog, int which) 
	        {
	        	String nmc = mixContext.noMarkersCheck();
	        	if (nmc != null)	{
	        		Toast.makeText(mixContext, nmc, Toast.LENGTH_LONG).show();
	        	}
	        	else	{
	        		int radioMetros = (int) Math.round(calcZoomLevel() * 1000);
	        		if (mixContext.noMarkerInRadius(radioMetros))	{
	    	        	Toast.makeText(mixContext, "Ajuste el radio de visibilidad mediante el menú de opciones para ver los lugares.", Toast.LENGTH_LONG).show();
	        		}
	        	}
	        		
	        	return;
	        }
	    });
		pd.show();
	}

	
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//Agregado
		CONTEXT = this;
		vAR = this;
		GestorConfiguracion.activity = (Activity) this;
		d = null;
		//FIN AGREGADO
		try {
			final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
			this.mWakeLock = pm.newWakeLock(
					PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "My Tag");
			locationMgr=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
//			locationMgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000,10, this);

			killOnError();
			//requestWindowFeature(Window.FEATURE_NO_TITLE);

			myZoomBar = new SeekBar(this);
			myZoomBar.setVisibility(View.INVISIBLE);
			myZoomBar.setMax(100);
			myZoomBar.setProgress(10); //x*20 = 200m
			myZoomBar.setOnSeekBarChangeListener(myZoomBarOnSeekBarChangeListener);		
			
			FrameLayout frameLayout = new FrameLayout(this);
			frameLayout.addView(myZoomBar);
			frameLayout.setPadding(10, 10, 10, 10);
			/* COMENTADO PARA PROBAR COMPORTAMIENTO ESTATICO
			dWindow = new PaintScreen();*/
			GestorConfiguracion.dWindow = new PaintScreen();
			camScreen = new CameraSurface(this);
			augScreen = new AugmentedView(this);
			setContentView(camScreen);

			addContentView(augScreen, new LayoutParams(
					LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

			addContentView(frameLayout, new FrameLayout.LayoutParams(
					LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT,
					Gravity.BOTTOM));

			mixContext = VInicial.getContext();
			mixContext.var = this;
			
			setZoomLevel();
			
			setProgressDialog();
		} catch (Exception ex) {
			doError(ex);
		}
		getSherlock().getActionBar().setTitle("Realidad aumentada");
		
		
	}

	public static int getActionbarSherlockHeight() {
		try {
			return vAR.getSherlock().getActionBar().getHeight();
		} catch(Exception e) {
			e.printStackTrace();
			return 0;
		}
	}
	
	@Override
	protected void onPause() {
		super.onPause();

		try {
			this.mWakeLock.release();

			try {
				sensorMgr.unregisterListener(this, sensorGrav);
			} catch (Exception ignore) {
			}
			try {
				sensorMgr.unregisterListener(this, sensorMag);
			} catch (Exception ignore) {
			}
			sensorMgr = null;

			try {
				locationMgr.removeUpdates(this);
			} catch (Exception ignore) {
			}
			locationMgr = null;

			try {
				mixContext.downloadManager.stop();
			} catch (Exception ignore) {
			}

			if (fError) {
				finish();
			}
		} catch (Exception ex) {
			//doError(ex);
		}
	}

	@Override
	protected void onResume() {
		super.onResume();
		if (DataView.volverInicio)	{
			finish();
			return;
		}
		
		int estadoDescarga = VInicial.dataView.getEstado();
		if ((estadoDescarga != MixState.DONE) || (DataView.actualizarMarkers)) {
			DataView.actualizarMarkers = false;
			//VInicial.dataView.applyCatFilter(VInicial.dataView.getDataHandler().getMarkerListTotal());
			Intent i = new Intent(VInicial.getContext(), VDownloading.class);
			i.putExtra("sigV", "ar");
			startActivity(i);
        	this.finish();
			return;
        }
		
		if (VInicial.dataView.getDataHandler().getMarkerListTotal().size() > 0)
			VBusqueda.primeraConsulta = false;
		
		try {
			this.mWakeLock.acquire();

			killOnError();
			mixContext.var = this;
			double angleX, angleY;

			int marker_orientation = -90;
			int rotation = Compatibility.getRotation(this);

			//display text from left to right and keep it horizontal
			angleX = Math.toRadians(marker_orientation);
			m1.set(1f, 0f, 0f, 0f, (float) Math.cos(angleX),
					(float) -Math.sin(angleX), 0f, (float) Math.sin(angleX),
					(float) Math.cos(angleX));

			angleX = Math.toRadians(marker_orientation);
			angleY = Math.toRadians(marker_orientation);
			if (rotation == 1) {
				m2.set(1f, 0f, 0f, 0f, (float) Math.cos(angleX),
						(float) -Math.sin(angleX), 0f,
						(float) Math.sin(angleX), (float) Math.cos(angleX));
				m3.set((float) Math.cos(angleY), 0f, (float) Math.sin(angleY),
						0f, 1f, 0f, (float) -Math.sin(angleY), 0f,
						(float) Math.cos(angleY));
			} else {
				m2.set((float) Math.cos(angleX), 0f, (float) Math.sin(angleX),
						0f, 1f, 0f, (float) -Math.sin(angleX), 0f,
						(float) Math.cos(angleX));
				m3.set(1f, 0f, 0f, 0f, (float) Math.cos(angleY),
						(float) -Math.sin(angleY), 0f,
						(float) Math.sin(angleY), (float) Math.cos(angleY));
			}
			m4.toIdentity();

			for (int i = 0; i < histR.length; i++) {
				histR[i] = new Matrix();
			}

			sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);

			sensors = sensorMgr.getSensorList(Sensor.TYPE_ACCELEROMETER);
			if (sensors.size() > 0) {
				sensorGrav = sensors.get(0);
			}

			sensors = sensorMgr.getSensorList(Sensor.TYPE_MAGNETIC_FIELD);
			if (sensors.size() > 0) {
				sensorMag = sensors.get(0);
			}

			sensorMgr.registerListener(this, sensorGrav, SENSOR_DELAY_GAME);
			sensorMgr.registerListener(this, sensorMag, SENSOR_DELAY_GAME);

			try {
				Criteria c = new Criteria();

				c.setAccuracy(Criteria.ACCURACY_FINE);
				//c.setBearingRequired(true);

				locationMgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
				locationMgr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000,10, this);
				locationMgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000,10, this);
				
				if ( (!locationMgr.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) && 
					 (!locationMgr.isProviderEnabled(LocationManager.GPS_PROVIDER)) )	{
					pd.dismiss();
					setErrorDialog();
				}
				try {
					Location gps=locationMgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);
					Location network=locationMgr.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
		             if(gps!=null && network!=null){
		                 if(gps.getTime()>network.getTime())
		                	 mixContext.curLoc = gps;
		                 else
		                	 mixContext.curLoc = network;
		             }
					 else if (gps != null)
						 mixContext.curLoc = gps;
					 else if (network != null)
						 mixContext.curLoc = network;
					
				} catch (Exception ex2) {
					ex2.printStackTrace();
				}
				
				mixContext.setLocationAtLastDownload(mixContext.curLoc);

				GeomagneticField gmf = new GeomagneticField((float) mixContext.curLoc
						.getLatitude(), (float) mixContext.curLoc.getLongitude(),
						(float) mixContext.curLoc.getAltitude(), System
						.currentTimeMillis());
				
				angleY = Math.toRadians(-gmf.getDeclination());
				m4.set((float) Math.cos(angleY), 0f,
						(float) Math.sin(angleY), 0f, 1f, 0f, (float) -Math
						.sin(angleY), 0f, (float) Math.cos(angleY));
				mixContext.declination = gmf.getDeclination();
			} catch (Exception ex) {
				Log.d("mixare", "GPS Initialize Error", ex);
			}
			
		} catch (Exception ex) {
			doError(ex);
			try {
				if (sensorMgr != null) {
					sensorMgr.unregisterListener(this, sensorGrav);
					sensorMgr.unregisterListener(this, sensorMag);
					sensorMgr = null;
				}
				if (locationMgr != null) {
					locationMgr.removeUpdates(this);
					locationMgr = null;
				}
				if (mixContext != null) {
					if (mixContext.downloadManager != null)
						mixContext.downloadManager.stop();
				}
			} catch (Exception ignore) {
			}
		}
		
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
//		int base = Menu.FIRST;
//		/*define the first*/
//		MenuItem item1 =menu.add(base, base, base, getString(R.string.menu_item_1)); //buscar por categoria
//		MenuItem item2 =menu.add(base, base+1, base+1,  getString(R.string.menu_item_2)); //buscar por servicios
//		MenuItem item3 =menu.add(base, base+2, base+2,  getString(R.string.menu_item_3)); //buscar (texto)
//		MenuItem item4 =menu.add(base, base+3, base+3,  getString(R.string.menu_item_4)); //ver en lista
//		MenuItem item5 =menu.add(base, base+4, base+4,  getString(R.string.menu_item_5)); //ver en mapa
//		MenuItem item6 =menu.add(base, base+5, base+5,  getString(R.string.menu_item_6)); //cambiar radio
		

//		/*assign icons to the menu items*/
//		item1.setIcon(R.drawable.ic_menu_filtrar);
//		item2.setIcon(android.R.drawable.ic_menu_share);
//		item3.setIcon(android.R.drawable.ic_menu_search);
//		item4.setIcon(android.R.drawable.ic_menu_sort_by_size);
//		item5.setIcon(R.drawable.ic_menu_mapa);
//		item6.setIcon(android.R.drawable.ic_menu_zoom);
		
		MenuInflater inflater = getSupportMenuInflater();
        inflater.inflate(R.menu.menu_ar, menu);
		
		if (DataView.viendoUnicoMarker)	{
			menu.findItem(R.id.arMenuCategoria).setVisible(false);
			menu.findItem(R.id.arMenuServicio).setVisible(false);
			menu.findItem(R.id.arMenuBuscar).setVisible(false);
			menu.findItem(R.id.arMenuVerEnLista).setVisible(false);
		}
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item){
		Intent i;
		switch(item.getItemId()){
			case R.id.arMenuCategoria:	//buscar por categoria
				i = new Intent(VInicial.getContext(), VFiltro.class);
				startActivity(i);
				break;
			case R.id.arMenuServicio: //Buscar por servicio
				i = new Intent(VInicial.getContext(), VServicios.class);
				startActivity(i);
				break;
			case R.id.arMenuBuscar: //Buscar (texto)
				if (DataView.enBusqueda == false)	{
					i = new Intent(VInicial.getContext(), VBusqueda.class);
					startActivity(i);
				}
				finish();
				break;
			case R.id.arMenuVerEnLista: //Ver en lista
				i = new Intent(VInicial.getContext(), VDownloading.class);
				i.putExtra("sigV", "lista");
				startActivity(i);
				break;
			case R.id.arMenuVerEnMapa:	//Ver en mapa
				i = new Intent(VInicial.getContext(), VDownloading.class);
				i.putExtra("sigV", "mapa");
				startActivity(i);
				finish();
				break;
			case R.id.arMenuRadio: //Radio de distancia
				myZoomBar.setVisibility(View.VISIBLE);
				zoomProgress = myZoomBar.getProgress();
				break;
		}
		return true;
	}
	
	public float calcZoomLevel(){
		float myout = (float) ((myZoomBar.getProgress() / 100f) * 2f);
		return myout;
	}

	private void setZoomLevel() {
		float myout = calcZoomLevel();
		
		VInicial.dataView.setRadius(myout);

		myZoomBar.setVisibility(View.INVISIBLE);
		zoomLevel = String.valueOf(myout);
	};
	
	private SeekBar.OnSeekBarChangeListener myZoomBarOnSeekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
		Toast t;

		public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
			float myout = calcZoomLevel();
			
			zoomLevel = String.valueOf(myout);
			zoomProgress = myZoomBar.getProgress();

			if (myout < 1f)	{
				int radioMetros = (int) Math.round(myout * 1000);
				t.setText("Radio: " + String.valueOf(radioMetros) + " m");
			}
			else	{
				t.setText("Radio: " + String.format("%.2g%n", myout) + " km");
			}

			t.show();
		}

		@SuppressLint("ShowToast")
		public void onStartTrackingTouch(SeekBar seekBar) {
			Context ctx = seekBar.getContext();
			t = Toast.makeText(ctx, "Radio: ", Toast.LENGTH_LONG);
		}

		public void onStopTrackingTouch(SeekBar seekBar) {
			myZoomBar.setVisibility(View.INVISIBLE);

			myZoomBar.getProgress();

			t.cancel();
			setZoomLevel();
			
    		int radioMetros = (int) Math.round(calcZoomLevel() * 1000);
        	String nmc = mixContext.noMarkersCheck();
    		if ( (mixContext.noMarkerInRadius(radioMetros)) && (nmc==null) )	{
	        	Toast.makeText(mixContext, "Ajuste el radio de visibilidad mediante el menú de opciones para ver los lugares.", Toast.LENGTH_LONG).show();
    		}
		}

	};


	public void onSensorChanged(SensorEvent evt) {
		try {
			if (evt.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
				grav[0] = evt.values[0];
				grav[1] = evt.values[1];
				grav[2] = evt.values[2];

				augScreen.postInvalidate();
			} else if (evt.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
				mag[0] = evt.values[0];
				mag[1] = evt.values[1];
				mag[2] = evt.values[2];

				augScreen.postInvalidate();
			}

			SensorManager.getRotationMatrix(RTmp, I, grav, mag);
			int rotation = Compatibility.getRotation(this);
			if (rotation == 1) {
				SensorManager.remapCoordinateSystem(RTmp, SensorManager.AXIS_X,
						SensorManager.AXIS_MINUS_Z, Rot);
			} else {
				SensorManager.remapCoordinateSystem(RTmp, SensorManager.AXIS_Y,
						SensorManager.AXIS_MINUS_Z, Rot);
			}
			tempR.set(Rot[0], Rot[1], Rot[2], Rot[3], Rot[4], Rot[5], Rot[6], Rot[7],
					Rot[8]);

//			System.out.println("------------------------------------------------");
//			System.out.println("\tRotM: ");
// 			System.out.println(RTmp[0]+"\t"+RTmp[1]+"\t"+RTmp[2]+"\t\t"+Rot[0]+"\t"+Rot[1]+"\t"+Rot[2]);
// 			System.out.println(RTmp[3]+"\t"+RTmp[4]+"\t"+RTmp[5]+"\t\t"+Rot[3]+"\t"+Rot[4]+"\t"+Rot[5]);
// 			System.out.println(RTmp[3]+"\t"+RTmp[4]+"\t"+RTmp[5]+"\t\t"+Rot[6]+"\t"+Rot[7]+"\t"+Rot[8]);
 			
			
			finalR.toIdentity();
			
			finalR.prod(m4);
//			System.out.println("m1: " + m1.toString());
//			System.out.println("tempR: " + tempR.toString());
//			System.out.println("m3: " + m3.toString());
//			System.out.println("m2: " + m2.toString());
//			System.out.println("m4: " + m4.toString());
			finalR.prod(m1);
//			System.out.println("m4 x m1 : " + finalR.toString());
			
			finalR.prod(tempR);
//			System.out.println("m4 x m1 x tempR : " + finalR.toString());
			
			finalR.prod(m3);
//			System.out.println("m4 x m1 x tempR x m3: " + finalR.toString());
			
			finalR.prod(m2);
//			System.out.println("m4 x m1 x tempR x m3 x m2: " + finalR.toString());
			
			finalR.invert(); 
//			System.out.println("finalR:");
//			System.out.println(+finalR.a1+"\t"+finalR.a2+"\t"+finalR.a3);
// 			System.out.println(+finalR.b1+"\t"+finalR.b2+"\t"+finalR.b3);
// 			System.out.println(+finalR.c1+"\t"+finalR.c2+"\t"+finalR.c3);
//			
// 			System.out.println("------------------------------------------------");
 			
			histR[rHistIdx].set(finalR);
			rHistIdx++;
			if (rHistIdx >= histR.length)
				rHistIdx = 0;

			smoothR.set(0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f);
			for (int i = 0; i < histR.length; i++) {
				smoothR.add(histR[i]);
			}
			smoothR.mult(1 / (float) histR.length);

			synchronized (mixContext.rotationM) {
				mixContext.rotationM.set(smoothR);
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent me) {
		try {
			killOnError();
			
			Rect rectgle= new Rect();
			Window window= getWindow();
			window.getDecorView().getWindowVisibleDisplayFrame(rectgle);
			int statusBarHeight= rectgle.top;
			
			float xPress = me.getRawX();
			float yPress = me.getRawY() - statusBarHeight;
			if (me.getAction() == MotionEvent.ACTION_UP) {
				VInicial.dataView.clickEvent(xPress, yPress);
			}

			return true;
		} catch (Exception ex) {
			//doError(ex);
			ex.printStackTrace();
			return super.onTouchEvent(me);
		}
	}
	

	public void onProviderDisabled(String provider) {
//		isGpsEnabled = locationMgr.isProviderEnabled(LocationManager.GPS_PROVIDER);
	}

	public void onProviderEnabled(String provider) {
//		isGpsEnabled = locationMgr.isProviderEnabled(LocationManager.GPS_PROVIDER);
	}

	public void onStatusChanged(String provider, int status, Bundle extras) {

	}

	public void onLocationChanged(Location location) {
		try {
			killOnError();
			location.setAltitude(0.0f);
			Log.v(VInicial.TAG,"Location Changed: "+location.getProvider()+" lat: "+location.getLatitude()+" lon: "+location.getLongitude()+" alt: "+location.getAltitude()+" acc: "+location.getAccuracy());


			mixContext.setLocationAtLastDownload(location);
			
			if (mixContext.isBetterLocation(location, mixContext.curLoc))	{
				synchronized (mixContext.curLoc) {
					mixContext.curLoc = location;
				}
				
				if (!VInicial.dataView.isFrozen())
					VInicial.dataView.getDataHandler().onLocationChanged(location);

				Log.d(VInicial.TAG, "Cambiando ubicacion actual en ar");
			}
			// setGpsEnabled(true);
			if ((!DataView.viendoUnicoMarker) && (pd.isShowing()))	{
				pd.dismiss();
			}

			if (pd.isShowing())	{
				pd.dismiss();
	        	String nmc = mixContext.noMarkersCheck();
        		int radioMetros = (int) Math.round(calcZoomLevel() * 1000);
        		if ( (mixContext.noMarkerInRadius(radioMetros)) && (nmc == null) )	{
    	        	Toast.makeText(mixContext, "Ajuste el radio de visibilidad mediante el menú de opciones para ver los lugares.", Toast.LENGTH_LONG).show();
        		}
			}
			//actualización de altura de markers
			
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	public void onAccuracyChanged(Sensor sensor, int accuracy) {
	}
}

/**
 * @author daniele
 *
 */
class CameraSurface extends SurfaceView implements SurfaceHolder.Callback {
	VAR app;
	SurfaceHolder holder;
	Camera camera;

	CameraSurface(Context context) {
		super(context);

		try {
			app = (VAR) context;

			holder = getHolder();
			holder.addCallback(this);
			holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		} catch (Exception ex) {

		}
	}

	public void surfaceCreated(SurfaceHolder holder) {
		try {
			if (camera != null) {
				try {
					camera.stopPreview();
				} catch (Exception ignore) {
				}
				try {
					camera.release();
				} catch (Exception ignore) {
				}
				camera = null;
			}

			camera = Camera.open();
			camera.setPreviewDisplay(holder);
		} catch (Exception ex) {
			try {
				if (camera != null) {
					try {
						camera.stopPreview();
					} catch (Exception ignore) {
					}
					try {
						camera.release();
					} catch (Exception ignore) {
					}
					camera = null;
				}
			} catch (Exception ignore) {

			}
		}
	}

	public void surfaceDestroyed(SurfaceHolder holder) {
		try {
			if (camera != null) {
				try {
					camera.stopPreview();
				} catch (Exception ignore) {
				}
				try {
					camera.release();
				} catch (Exception ignore) {
				}
				camera = null;
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	
	public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
		try {
			Camera.Parameters parameters = camera.getParameters();
			try {
				List<Camera.Size> supportedSizes = null;
				//On older devices (<1.6) the following will fail
				//the camera will work nevertheless
				supportedSizes = Compatibility.getSupportedPreviewSizes(parameters);

				//preview form factor
				float ff = (float)w/h;
				Log.d("Mixare", "Screen res: w:"+ w + " h:" + h + " aspect ratio:" + ff);

				//holder for the best form factor and size
				float bff = 0;
				int bestw = 0;
				int besth = 0;
				Iterator<Camera.Size> itr = supportedSizes.iterator();
				
				//we look for the best preview size, it has to be the closest to the
				//screen form factor, and be less wide than the screen itself
				//the latter requirement is because the HTC Hero with update 2.1 will
				//report camera preview sizes larger than the screen, and it will fail
				//to initialize the camera
				//other devices could work with previews larger than the screen though
				while(itr.hasNext()) {
					Camera.Size element = itr.next();
					//current form factor
					float cff = (float)element.width/element.height;
					//check if the current element is a candidate to replace the best match so far
					//current form factor should be closer to the bff
					//preview width should be less than screen width
					//preview width should be more than current bestw
					//this combination will ensure that the highest resolution will win
					Log.d("Mixare", "Candidate camera element: w:"+ element.width + " h:" + element.height + " aspect ratio:" + cff);
					if ((ff-cff <= ff-bff) && (element.width <= w) && (element.width >= bestw)) {
						bff=cff;
						bestw = element.width;
						besth = element.height;
					}
				} 
				Log.d("Mixare", "Chosen camera element: w:"+ bestw + " h:" + besth + " aspect ratio:" + bff);
				//Some Samsung phones will end up with bestw and besth = 0 because their minimum preview size is bigger then the screen size.
				//In this case, we use the default values: 480x320
				if ((bestw == 0) || (besth == 0)){
					Log.d("Mixare", "Using default camera parameters!");
					bestw = 480;
					besth = 320;
				}
				parameters.setPreviewSize(bestw, besth);
			} catch (Exception ex) {
				parameters.setPreviewSize(480 , 320);
			}

			camera.setParameters(parameters);
			camera.startPreview();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
}

class AugmentedView extends View {
	VAR app;
	int xSearch=200;
	int ySearch = 10;
	int searchObjWidth = 0;
	int searchObjHeight=0;
	
	//Agregado como mejora de performance
		private Paint zoomPaint = new Paint();
		private String startKM = "0m";	
		private String  endKM = "2km";

	public AugmentedView(Context context) {
		super(context);
		
		zoomPaint.setColor(Color.WHITE);
		zoomPaint.setTextSize(14);
		try {
			app = (VAR) context;

			app.killOnError();
		} catch (Exception ex) {
			app.doError(ex);
		}

	}

	@Override
	protected void onDraw(Canvas canvas) {
		try {

			app.killOnError();
/* COMENTADO PARA PROBAR FUNCIONAMIENTO ESTATICO
			VAR.dWindow.setWidth(canvas.getWidth());
			VAR.dWindow.setHeight(canvas.getHeight());

			VAR.dWindow.setCanvas(canvas);
			
			VInicial.dataView.init(VAR.dWindow.getWidth(), VAR.dWindow.getHeight());
*/
			GestorConfiguracion.dWindow.setWidth(canvas.getWidth());
			GestorConfiguracion.dWindow.setHeight(canvas.getHeight());
			GestorConfiguracion.dWindow.setCanvas(canvas);

			VInicial.dataView.init(GestorConfiguracion.dWindow.getWidth(), GestorConfiguracion.dWindow.getHeight());
				
			if (app.isZoombarVisible()){
				/*Paint zoomPaint = new Paint();
				
				zoomPaint.setColor(Color.WHITE);
				zoomPaint.setTextSize(14);
				XString startKM, endKM;
				endKM = "2km";
				startKM = "0m"; */
				canvas.drawText(startKM, canvas.getWidth()/100*4, canvas.getHeight()/100*85, zoomPaint);
				canvas.drawText(endKM, canvas.getWidth()/100*99, canvas.getHeight()/100*85, zoomPaint);
			}
/* COMENTADO PARA PROBAR COMPORTAMIENTO ESTATICO
			VInicial.dataView.draw(VAR.dWindow);*/
			VInicial.dataView.draw(GestorConfiguracion.dWindow);
		} catch (Exception ex) {
			app.doError(ex);
		}
	}
}
